package com.centaline.androidsalesblog.base;

import android.support.v7.widget.AppCompatTextView;
import android.view.LayoutInflater;
import android.view.View;

import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.MapStatus;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.Overlay;
import com.baidu.mapapi.map.UiSettings;
import com.baidu.mapapi.model.LatLng;
import com.centaline.androidsalesblog.R;
import com.centaline.androidsalesblog.model.databaseobject.CityCenterDo;
import com.centaline.androidsalesblog.rx.database.RxDataBase;
import com.trello.rxlifecycle.FragmentEvent;

import java.util.ArrayList;
import java.util.concurrent.TimeUnit;

import rx.Observable;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Action1;
import rx.schedulers.Schedulers;

/**
 * 列表模式地图基类
 * Created by guilin on 16/4/12.
 */
public abstract class BaseListMapFragment<T> extends BaseFragment implements BaiduMap.OnMapLoadedCallback,
        BaiduMap.OnMapStatusChangeListener {

    protected MapView mapView;
    protected BaiduMap baiduMap;
    protected View clickView;//点击显示的view
    protected AppCompatTextView atv_mark_num, atv_mark_title;

    protected ArrayList<T> mapArrayList = new ArrayList<>();//地图显示数据
    protected ArrayList<String> keyArray = new ArrayList<>();//保存关键字

    protected int mapStatusChangeTag;//地图状态改变标签
    protected LatLng cityCenter;//城市中心点
    protected int targetScreenY;//中心点
    protected int bottomSheetTag;//bottomSheet状态标签
    protected boolean isReset;//是否需要重置
    protected boolean hasNews;//是否有新的数据
    protected Overlay overlay;

    @Override
    public void onResume() {
        mapView.onResume();
        super.onResume();
    }

    @Override
    public void onPause() {
        mapView.onPause();
        super.onPause();
    }

    @Override
    public void onDestroy() {
        mapView.onDestroy();
        super.onDestroy();
    }

    @Override
    protected int setLayoutId() {
        return R.layout.fragment_map;
    }

    @Override
    protected void findViews(View view) {
        mapView = (MapView) view.findViewById(R.id.mapView);
    }

    @Override
    protected void initView() {
        clickView = LayoutInflater.from(getActivity()).inflate(R.layout.layout_map_esf_xz, null);
        atv_mark_num = (AppCompatTextView) clickView.findViewById(R.id.atv_mark_num);
        atv_mark_title = (AppCompatTextView) clickView.findViewById(R.id.atv_mark_title);

        baiduMap = mapView.getMap();
        UiSettings uiSettings = baiduMap.getUiSettings();
        uiSettings.setCompassEnabled(true);
        uiSettings.setOverlookingGesturesEnabled(false);
        uiSettings.setRotateGesturesEnabled(false);
        baiduMap.setMyLocationEnabled(true);
        baiduMap.setOnMapStatusChangeListener(this);
        baiduMap.setOnMapLoadedCallback(this);
    }

    @Override
    public void onMapLoaded() {
        mapView.showZoomControls(false);
        baiduMap.setMaxAndMinZoomLevel(20f, 9f);
        RxDataBase.cityCenterDo()
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .compose(this.<CityCenterDo>bindUntilEvent(FragmentEvent.DESTROY))
                .subscribe(new Action1<CityCenterDo>() {
                    @Override
                    public void call(CityCenterDo cityCenterDo) {
                        cityCenter = new LatLng(cityCenterDo.getLat(), cityCenterDo.getLng());
                        baiduMap.setMapStatus(MapStatusUpdateFactory.newLatLngZoom(cityCenter, 9f));
                        setMapStatusLimits();
                    }
                });
    }

    /**
     * 限制地图显示范围[本城市,级别:9f]
     */
    private void setMapStatusLimits() {
        Observable
                .interval(0, 1, TimeUnit.SECONDS)
                .take(2)
                .observeOn(AndroidSchedulers.mainThread())
                .compose(this.<Long>bindUntilEvent(FragmentEvent.DESTROY))
                .subscribe(new Action1<Long>() {
                    @Override
                    public void call(Long aLong) {
                        if (aLong == 1) {
                            baiduMap.setMapStatusLimits(baiduMap.getMapStatus().bound);
                        }
                    }
                });
    }

    /**
     * 设置地图显示数据
     *
     * @param reset 是否重置地图显示
     */
    public void setMapArrayList(ArrayList<T> temp, boolean reset) {
        isReset = reset;
        if (reset) {
            keyArray.clear();
            mapArrayList.clear();
        }
        if (temp != null) {
            mapArrayList.addAll(temp);
        }
        if (isVisible) {//地图可见则更新地图数据
            hasNews = false;
            if (reset) {
                resetMap();
            } else {
                refreshMap();
            }
        } else {
            hasNews = true;
        }
    }

    @Override
    protected void loadData() {
        if (hasNews) {
            hasNews = false;
            if (isReset) {
                resetMap();
            } else {
                refreshMap();
            }
        }
    }

    /**
     * 地图显示重置
     */
    protected abstract void resetMap();

    /**
     * 有新数据,刷新地图
     */
    protected abstract void refreshMap();

    /**
     * 根据bottomSheet设置地图状态
     *
     * @param reset 是否还原
     */
    public void updateMapStatusByBottomSheet(boolean reset) {
        if (reset &&
                bottomSheetTag == 1) {
            bottomSheetTag = 0;
            baiduMap.animateMapStatus(MapStatusUpdateFactory.scrollBy(0,
                    -targetScreenY * 2 / 3), 150);
            if (overlay != null) {
                overlay.remove();
                overlay = null;
            }
        } else if (bottomSheetTag == 0) {
            bottomSheetTag = 1;
            baiduMap.animateMapStatus(MapStatusUpdateFactory.scrollBy(0,
                    targetScreenY * 2 / 3), 150);
        }
    }

    @Override
    public void onMapStatusChangeStart(MapStatus mapStatus) {

    }

    @Override
    public void onMapStatusChange(MapStatus mapStatus) {

    }

    @Override
    public void onMapStatusChangeFinish(MapStatus mapStatus) {
        if (targetScreenY == 0) {
            targetScreenY = mapStatus.targetScreen.y;
        }
    }
}
